package com.xiaohua.system.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

import com.xiaohua.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.xiaohua.system.domain.XhOperations;
import com.xiaohua.system.mapper.XhUsersMapper;
import com.xiaohua.system.domain.XhUsers;
import com.xiaohua.system.service.IXhUsersService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 用户管理Service业务层处理
 *
 * @author 小花
 * @date 2025-03-22
 */
@Service
public class XhUsersServiceImpl implements IXhUsersService {
    private static final Logger log = LoggerFactory.getLogger(XhUsersServiceImpl.class);
    
    @Autowired
    private XhUsersMapper xhUsersMapper;

    /**
     * 用户名密码登录
     *
     * @param username 用户名
     * @param password 密码
     * @return 用户信息
     */
    @Override
    public XhUsers loginByUsername(String username, String password) {
        try {
            log.info("操作=登录验证, 用户={}", username);
            
            // 1. 根据用户名查询用户
            XhUsers userParam = new XhUsers();
            userParam.setUsername(username);
            List<XhUsers> users = xhUsersMapper.selectXhUsersList(userParam);
            
            // 2. 判断用户是否存在
            if (users == null || users.isEmpty()) {
                log.info("操作=登录验证, 用户={}, 结果=失败, 原因=用户不存在", username);
                return null;
            }
            
            XhUsers user = users.get(0);
            log.info("操作=用户查询, 用户={}, 结果=找到, 用户ID={}", username, user.getUserId());
            
            // 3. 验证密码
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            boolean matched = passwordEncoder.matches(password, user.getPassword());
            
            if (matched) {
                log.info("操作=密码验证, 用户={}, 结果=成功", username);
                return user;
            } else {
                log.info("操作=密码验证, 用户={}, 结果=失败, 原因=密码不匹配", username);
                return null;
            }
        } catch (Exception e) {
            log.error("操作=登录验证, 用户={}, 结果=异常, 错误={}", username, e.getMessage());
            return null;
        }
    }

    /**
     * 查询用户管理
     *
     * @param userId 用户管理主键
     * @return 用户管理
     */
    @Override
    public XhUsers selectXhUsersByUserId(Long userId) {
        return xhUsersMapper.selectXhUsersByUserId(userId);
    }

    /**
     * 查询用户管理列表
     *
     * @param xhUsers 用户管理
     * @return 用户管理
     */
    @Override
    public List<XhUsers> selectXhUsersList(XhUsers xhUsers) {
        return xhUsersMapper.selectXhUsersList(xhUsers);
    }

    /**
     * 新增用户管理
     *
     * @param xhUsers 用户管理
     * @return 结果
     */
    @Transactional
    @Override
    public int insertXhUsers(XhUsers xhUsers) {
        int rows = xhUsersMapper.insertXhUsers(xhUsers);
        insertXhOperations(xhUsers);
        return rows;
    }

    /**
     * 修改用户管理
     *
     * @param xhUsers 用户管理
     * @return 结果
     */
    @Transactional
    @Override
    public int updateXhUsers(XhUsers xhUsers) {
        xhUsersMapper.deleteXhOperationsByUserId(xhUsers.getUserId());
        insertXhOperations(xhUsers);
        return xhUsersMapper.updateXhUsers(xhUsers);
    }

    /**
     * 批量删除用户管理
     *
     * @param userIds 需要删除的用户管理主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteXhUsersByUserIds(Long[] userIds) {
        xhUsersMapper.deleteXhOperationsByUserIds(userIds);
        return xhUsersMapper.deleteXhUsersByUserIds(userIds);
    }

    /**
     * 删除用户管理信息
     *
     * @param userId 用户管理主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteXhUsersByUserId(Long userId) {
        xhUsersMapper.deleteXhOperationsByUserId(userId);
        return xhUsersMapper.deleteXhUsersByUserId(userId);
    }

    /**
     * 新增操作记录信息
     *
     * @param xhUsers 用户管理对象
     */
    public void insertXhOperations(XhUsers xhUsers) {
        List<XhOperations> xhOperationsList = xhUsers.getXhOperationsList();
        Long userId = xhUsers.getUserId();
        if (StringUtils.isNotNull(xhOperationsList)) {
            List<XhOperations> list = new ArrayList<XhOperations>();
            for (XhOperations xhOperations : xhOperationsList) {
                xhOperations.setUserId(userId);
                list.add(xhOperations);
            }
            if (list.size() > 0) {
                xhUsersMapper.batchXhOperations(list);
            }
        }
    }
    
    /**
     * 密码脱敏处理
     * 只显示密码的前10位，后面用*代替
     */
    private String maskPassword(String password) {
        if (password == null || password.length() <= 10) {
            return password;
        }
        return password.substring(0, 10) + "******";
    }
    
    /**
     * 将手机号中间部分替换为*号
     */
    private String maskMobile(String mobile) {
        if (mobile == null || mobile.length() != 11) {
            return mobile != null ? mobile : "null";
        }
        return mobile.substring(0, 3) + "****" + mobile.substring(7);
    }
    
    /**
     * 获取异常堆栈信息作为字符串
     */
    private String getStackTraceAsString(Exception e) {
        if (e == null) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append(e.toString()).append("\n");
        for (StackTraceElement element : e.getStackTrace()) {
            sb.append("\tat ").append(element.toString()).append("\n");
        }
        return sb.toString();
    }
    
    /**
     * 检查用户tokens是否足够
     * 
     * @param userId 用户ID
     * @return 如果用户tokens足够返回true，否则返回false
     */
    @Override
    public boolean checkUserTokens(Long userId) {
        try {
            XhUsers user = xhUsersMapper.selectXhUsersByUserId(userId);
            if (user == null) {
                log.error("操作=检查用户tokens, 用户ID={}, 结果=失败, 原因=用户不存在", userId);
                return false;
            }
            
            Long tokens = user.getTokens();
            log.info("操作=检查用户tokens, 用户ID={}, 当前tokens={}", userId, tokens);
            
            return tokens != null && tokens > 0;
        } catch (Exception e) {
            log.error("操作=检查用户tokens, 用户ID={}, 结果=异常, 错误={}", userId, e.getMessage());
            return false;
        }
    }
    
    /**
     * 扣减用户tokens
     * 
     * @param userId 用户ID
     * @param amount 扣减的tokens数量，默认为1
     * @return 扣减成功返回true，否则返回false
     */
    @Override
    @Transactional
    public boolean deductUserTokens(Long userId, int amount) {
        if (amount <= 0) {
            log.error("操作=扣减用户tokens, 用户ID={}, 结果=失败, 原因=扣减数量必须大于0", userId);
            return false;
        }
        
        try {
            XhUsers user = xhUsersMapper.selectXhUsersByUserId(userId);
            if (user == null) {
                log.error("操作=扣减用户tokens, 用户ID={}, 结果=失败, 原因=用户不存在", userId);
                return false;
            }
            
            Long tokens = user.getTokens();
            if (tokens == null || tokens < amount) {
                log.error("操作=扣减用户tokens, 用户ID={}, 当前tokens={}, 扣减数量={}, 结果=失败, 原因=tokens不足", userId, tokens, amount);
                return false;
            }
            
            user.setTokens(tokens - amount);
            int rows = xhUsersMapper.updateXhUsers(user);
            
            if (rows > 0) {
                log.info("操作=扣减用户tokens, 用户ID={}, 扣减前tokens={}, 扣减数量={}, 扣减后tokens={}, 结果=成功", 
                        userId, tokens, amount, user.getTokens());
                return true;
            } else {
                log.error("操作=扣减用户tokens, 用户ID={}, 结果=失败, 原因=更新数据库失败", userId);
                return false;
            }
        } catch (Exception e) {
            log.error("操作=扣减用户tokens, 用户ID={}, 结果=异常, 错误={}", userId, e.getMessage());
            return false;
        }
    }
    
    /**
     * 扣减用户tokens，默认扣减1个token
     * 
     * @param userId 用户ID
     * @return 扣减成功返回true，否则返回false
     */
    @Override
    public boolean deductUserTokens(Long userId) {
        return deductUserTokens(userId, 1);
    }
}
